<template>
  <div id="Box">
    <input type="file" name="" id="" @change="fileChange($event)" />
    <button @click="uploadFile()">上传</button>
  </div>
</template>

<script setup lang="ts">
import { reactive } from "vue";
import { Res } from "../interfaces";
import axios from "axios";
import SparkMD5 from "spark-md5";
import { useMyHTTP } from "../http";
const chunkSize = 1024 * 1024 * 20; // Read in chunks of 20MB
const { header } = useMyHTTP();

const uploadByMd5 = async (): Promise<boolean> => {
  const { data, code, msg } = await axios
    .post<Res>(
      `http://192.168.1.147:8082/layer/checkByMd5`,
      {
        sourceMd5: datas.md5,
        parentId: "1",
        type: "DOM",
        name: "测试分片",
      },
      header
    )
    .then((r) => r.data);

  if (code == 200) {
    console.log(data["msg"]);
    return data["state"] == 0;
  } else {
    console.log(msg);
    return false;
  }
};

const doUploadFile = async (chunk: number = 0) => {
  const start = chunk * chunkSize;
  const end = Math.min((chunk + 1) * chunkSize, (datas.file as File).size);
  const formData = new FormData();
  formData.append("name", "测试分片");
  formData.append("type", "DOM");
  formData.append("md5", datas.md5);
  formData.append("parentId", "1");
  formData.append("chunks", datas.chunks as any);
  formData.append("chunk", `${chunk}`);
  formData.append("chunkSize", `${chunkSize}`);
  formData.append("file", datas.file?.slice(start, end) as any);
  formData.append("fileName", (datas.file as File).name);

  const { data, msg, code } = await axios
    .post<Res>(`http://192.168.1.147:8082/layer/addLayer`, formData, header)
    .then((res) => res.data);

  console.log(data);
  const { nextIndex, uploadComplete } = data;
  if (!uploadComplete) {
    doUploadFile(nextIndex);
  } else {
    console.log("上传完成！");
  }
};

const datas = reactive<{
  md5: string;
  file: File | undefined;
  chunks: number;
}>({ md5: "", chunks: 0, file: undefined });

const uploadFile = async () => {
  if (!datas.md5) {
    console.log("正在计算md5！请稍后...");
    return;
  }

  if (await uploadByMd5()) {
    await doUploadFile(0);
  }
};

const getFileMd5 = (file: File) => {
  datas.md5 = "";
  datas.file = file;
  const spark = new SparkMD5.ArrayBuffer();
  const chunks = Math.ceil(file.size / chunkSize);
  datas.chunks = chunks;
  let currentChunk = 0;

  const fileReader = new FileReader();
  fileReader.onload = (evt) => {
    spark.append(evt.target?.result as any);
    console.log(`第${currentChunk}片读取完成！`);
    currentChunk++;
    if (currentChunk < chunks) {
      loadNext();
    } else {
      datas.md5 = spark.end();
      console.log(`文件md5为：${datas.md5}`);
    }
  };

  const loadNext = () => {
    const start = currentChunk * chunkSize;
    const end = Math.min((currentChunk + 1) * chunkSize, file.size);
    fileReader.readAsArrayBuffer(file.slice(start, end));
  };

  loadNext();
};

const fileChange = (evt) => {
  getFileMd5(evt.target.files[0]);
};
</script>

<style scoped lang="less">
#Box {
}
</style>
